package com.gwq.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gwq.dto.MessageDto;
import com.gwq.dto.MessageReplyDto;
import com.gwq.entity.*;
import com.gwq.mapper.*;
import com.gwq.param.MessageParam;
import com.gwq.param.MessageGiveLikeAddParam;
import com.gwq.service.MessageFileService;
import com.gwq.service.MessageReplyService;
import com.gwq.service.MessageService;
import com.gwq.service.SysUserService;
import com.gwq.utils.DateUtils;
import com.gwq.utils.LocalCacheUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.rmi.ServerException;
import java.security.Principal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class MessageServicelmpl extends ServiceImpl<MessageMapper, Message> implements MessageService {

    @Value("${local.filePath}")
    private String localFilePath;

    @Autowired
    private MessageFileMapper messageFileMapper;

    @Autowired
    private MessageFileService messageFileService;

    @Autowired
    private MessageReplyService messageReplyService;
    @Autowired
    private MessageReplyMapper messageReplyMapper;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private MessageGiveLikeMapper messageGiveLikeMapper;

    @Autowired
    private MessageReplyGiveLikeMapper messageReplyGiveLikeMapper;

    @Override
    public void addMessage(Message message) {

        message.setCreatedAt(DateUtils.getYyyyMMddHHmmss(new Date()));
        message.setGiveLike(0);
        message.setMessage(message.getMessage().replace("\n","<br>"));
        save(message);

        //保存文件
        if(message.getFileUrls()!=null) {

            QueryWrapper<MessageFile> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("message_id",message.getId());
            List<MessageFile>  messageFiles = messageFileMapper.selectList(queryWrapper);
            if(messageFiles!=null){
                List<String> ids = messageFiles.stream().map(t->t.getId()).collect(Collectors.toList());
                messageFileMapper.deleteBatchIds(ids);
            }

            List<MessageFile> messageFileList = new ArrayList<>();
            message.getFileUrls().stream().forEach(t->{
                MessageFile messageFile = new MessageFile();
                messageFile.setMessageId(message.getId());
                messageFile.setFileUrl(t);
                messageFile.setFileType(fileType(t));
                messageFileList.add(messageFile);

            });
            messageFileService.addFiles(messageFileList);
        }
    }

    @Override
    public void updateMessage(Message message) {
        if(message.getId()!=null){
            message.setUpdatedAt(DateUtils.getYyyyMMddHHmmss(new Date()));
            updateById(message);
        }
    }

    @Override
    public void deleteMessage(String[] ids) {
        removeByIds(Arrays.asList(ids));
    }

    @Override
    public Message getByMessageId(String id) {
        return getById(id);
    }

    @Override
    public Page<MessageDto> pageMessage(MessageParam messageParam, Principal principal) {
        SysUser sysUser = sysUserService.getByUserName(principal.getName());
        Page<MessageDto> page  = new Page<>(messageParam.getPage(),messageParam.getSize());
        Page<MessageDto>  page1 = baseMapper.pageMessage(page,messageParam.getKeyValues(),messageParam.getTitle(),messageParam.getBegTime(),messageParam.getEndTime(),messageParam.getSort());
        if(page1.getRecords()!=null){
            List<String> ids  = page1.getRecords().stream().map(t->t.getId()).collect(Collectors.toList());

            /*QueryWrapper<MessageReply> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("message_id",ids);
            List<MessageReply> messageReplies = messageReplyMapper.selectList(queryWrapper);

            QueryWrapper<MessageFile> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.in("message_id",ids);
            List<MessageFile> messageFiles = messageFileMapper.selectList(queryWrapper1);*/

            QueryWrapper<MessageGiveLike> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.eq("created_by",sysUser.getId());
            queryWrapper2.in("message_id",ids);
            List<MessageGiveLike> messageGiveLikes = messageGiveLikeMapper.selectList(queryWrapper2);

            QueryWrapper<MessageReply> queryWrapper3 = new QueryWrapper<>();
            queryWrapper3.in("message_id",ids);
            List<MessageReply> messageReplies = messageReplyMapper.selectList(queryWrapper3);
            Map<String,List<MessageReply>> riskMap = messageReplies.stream().collect(Collectors.groupingBy(MessageReply::getMessageId));


            Map<String,List<MessageGiveLike>> giveMap = messageGiveLikes.stream().collect(Collectors.groupingBy(MessageGiveLike::getMessageId));
            /*Map<String,List<MessageReply>> replyMap = messageReplies.stream().collect(Collectors.groupingBy(MessageReply::getMessageId));
            Map<String,List<MessageFile>> fileMap = messageFiles.stream().collect(Collectors.groupingBy(MessageFile::getMessageId));*/
            page1.getRecords().stream().forEach(o->{

                if(o.getMessage()!=null&&o.getMessage()!="") {
                    o.setMessage(o.getMessage().replace("<br>", "\n"));
                }
                if(riskMap.get(o.getId())!=null){
                    Long num = riskMap.get(o.getId()).stream().count();
                    o.setReviewNum(num);
                }
                /*if(replyMap.get(o.getId())!=null){
                    o.setMessageReplies(replyMap.get(o.getId()));
                }*/
                if(giveMap.get(o.getId())!=null){
                    o.setLike(true);
                }else{
                    o.setLike(false);
                }
                /*if(fileMap.get(o.getId())!=null){
                    List<MessageFile> messageFileList = new ArrayList<>();
                    fileMap.get(o.getId()).stream().forEach(t->{
                        MessageFile messageFile = new MessageFile();
                        BeanUtils.copyProperties(t,messageFile);
                        //给ipad测试环境使用的ip方式 正式环境记得注释
                        messageFile.setFileUrl("http://110.41.138.146/files/"+t.getFileUrl());
                        messageFile.setFileName(t.getFileUrl());
                        messageFile.setType(t.getFileUrl().substring(t.getFileUrl().lastIndexOf('.')+1,t.getFileUrl().length()));
                        messageFileList.add(messageFile);
                    });
                    o.setMessageFiles(messageFileList);
                }*/
            });
        }
        return page1;
    }

    @Override
    public String uploadPicture(MultipartFile picture) throws ServerException {
        // 生成文件名 RiskVideoTable.Id+"_"+"VerticalView"
        String uuid = UUID.randomUUID().toString().replaceAll("-","");
        String fileName = uuid+"_riskInvitation_"+picture.getOriginalFilename();
        InputStream inputStream = null;

        //转换图片的清晰度
        //压缩图片的文件名为 RiskVideoTable.Id+"_"+"VagueVerticalView"
        try {
            String fileNameVague = uuid+"_riskInvitation_"+picture.getOriginalFilename();
            byte[] bytes;
            bytes = picture.getBytes();
            org.apache.commons.io.FileUtils.writeByteArrayToFile(new File(localFilePath + fileNameVague), bytes);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("转换图片的清晰度并保存失败");
        }

        try {
            inputStream = picture.getInputStream();
            uploadFile(inputStream, fileName);
        } catch (IOException e) {
            throw new ServerException("俯瞰图上传失败！");
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return fileName;
    }

    @Override
    public void messageAddReply(MessageReply messageReply, Principal principal) {
        messageReply.setCreatedAt(DateUtils.getYyyyMMddHHmmss(new Date()));
        messageReplyService.addReply(messageReply);
    }

    @Override
    public void addAndUpdateGiveLike(MessageGiveLikeAddParam param, Principal principal) {

        SysUser sysUser = sysUserService.getByUserName(principal.getName());

        QueryWrapper<MessageGiveLike> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("created_by",sysUser.getId());
        queryWrapper.eq("message_id",param.getMessageId());

        MessageGiveLike messageGiveLike = messageGiveLikeMapper.selectOne(queryWrapper);

        Message message = getById(param.getMessageId());
        if(message!=null&& messageGiveLike !=null){
            messageGiveLikeMapper.deleteById(messageGiveLike.getId());

            message.setGiveLike(message.getGiveLike()-1);
            updateById(message);
        }else{
            MessageGiveLike messageGiveLike1 = new MessageGiveLike();
            messageGiveLike1.setMessageId(param.getMessageId());
            messageGiveLike1.setCreatedBy(sysUser.getId());
            messageGiveLike1.setCreatedAt(DateUtils.getYyyyMMddHHmmss(new Date()));
            messageGiveLikeMapper.insert(messageGiveLike1);


            message.setGiveLike(message.getGiveLike()+1);
            updateById(message);
        }
    }

    @Override
    public Page getRemarkPage(MessageGiveLikeAddParam param, Principal principal) {
        SysUser sysUser = sysUserService.getByUserName(principal.getName());
        Page<MessageReplyDto> page = new Page<>(param.getPage(),param.getSize());
        page= messageReplyMapper.pageReply(page,param.getMessageId(),param.getSort());


        if(page.getRecords()!=null){
            List<String> ids = page.getRecords().stream().map(t->t.getId()).collect(Collectors.toList());
            QueryWrapper<MessageReplyGiveLike> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("created_by",sysUser.getId());
            queryWrapper.in("reply_id",ids);
            List<MessageReplyGiveLike> messageReplyGiveLikes = messageReplyGiveLikeMapper.selectList(queryWrapper);
            Map<String,List<MessageReplyGiveLike>> giveMap = messageReplyGiveLikes.stream().collect(Collectors.groupingBy(MessageReplyGiveLike::getReplyId));

            page.getRecords().stream().forEach(o->{
                if(giveMap.get(o.getId())!=null){
                    o.setLike(true);
                }else{
                    o.setLike(false);
                }
            });
        }

        return page;
    }

    @Override
    public void addAndUpdateRemark(MessageGiveLikeAddParam param, Principal principal) {
        SysUser sysUser = sysUserService.getByUserName(principal.getName());
        MessageReply messageReply = new MessageReply();
        messageReply.setMessageId(param.getMessageId());
        messageReply.setContent(param.getContent());
        messageReply.setCreatedAt(DateUtils.getYyyyMMddHHmmss(new Date()));
        messageReply.setGiveLike(0);
        messageReply.setCreatedBy(sysUser.getId());
        messageReplyMapper.insert(messageReply);
    }

    @Override
    public void giveLikeRemark(MessageGiveLikeAddParam param, Principal principal) {

        SysUser sysUser = sysUserService.getByUserName(principal.getName());

        QueryWrapper<MessageReplyGiveLike> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("created_by",sysUser.getId());
        queryWrapper.eq("reply_id",param.getMessageId());
        MessageReplyGiveLike messageReplyGiveLike = messageReplyGiveLikeMapper.selectOne(queryWrapper);

        MessageReply messageReply = messageReplyMapper.selectById (param.getReplyId());
        if(messageReply!=null&&messageReplyGiveLike!=null){
            messageReplyGiveLikeMapper.deleteById(messageReplyGiveLike.getId());

            messageReply.setGiveLike(messageReply.getGiveLike()-1);
            messageReplyMapper.updateById(messageReply);
        }else{
            MessageReplyGiveLike riskInvitationGiveLikeRemark1 = new MessageReplyGiveLike();
            riskInvitationGiveLikeRemark1.setReplyId(param.getReplyId());
            riskInvitationGiveLikeRemark1.setCreatedBy(sysUser.getId());
            riskInvitationGiveLikeRemark1.setCreatedAt(DateUtils.getYyyyMMddHHmmss(new Date()));
            messageReplyGiveLikeMapper.insert(riskInvitationGiveLikeRemark1);

            messageReply.setGiveLike(messageReply.getGiveLike()+1);
            messageReplyMapper.updateById(messageReply);
        }
    }

    @Override
    public Page<MessageDto> myPage(MessageParam messageParam, Principal principal) {
        SysUser sysUser = sysUserService.getByUserName(principal.getName());
        Page<MessageDto> page  = new Page<>(messageParam.getPage(),messageParam.getSize());
        String userId="";
        if(messageParam.getMyType()==2) {
            if (!sysUser.getUserName().equalsIgnoreCase("admin")&&!sysUser.getUserName().equalsIgnoreCase("vue123456")) {
                userId = sysUser.getId();
            }
        }else{
            userId = sysUser.getId();
        }

        Page<MessageDto>  page1 = baseMapper.MyPage(page,messageParam.getKeyValues(),messageParam.getBegTime(),messageParam.getEndTime(),userId,messageParam.getSort());
        if(page1.getRecords()!=null){
            page1.getRecords().forEach(o->{
                if(o.getMessage()!=null&&o.getMessage()!="") {
                    o.setMessage(o.getMessage().replace("<br>", "\n"));
                }
            });
        }
        return page1;
    }

    public boolean uploadFile(InputStream inputStream, String saveName) {
        try {
            byte[] byt = new byte[inputStream.available()];
            inputStream.read(byt);
            LocalCacheUtils.getFile(byt, localFilePath, saveName);

        } catch (IOException e) {

        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }

    private  Integer fileType(String fileName){

        int i = fileName.lastIndexOf('.');
        String name = fileName.substring(i+1,fileName.length());
        if(name.contains("png")||name.contains("jpg")||name.contains("jpeg")||name.contains("PNG")||name.contains("JPG")||name.contains("JPEG")){
            return 1;
        }else{
            return 0;
        }
    }
}
